﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.LinearAlgebra.Generic;
using innovations.util;
using innovations.util.exts.msft;
using innovations.util.exts.mathdotnet;

namespace innovations.ml.core
{
    public abstract class Cost
    {
        public abstract static void Compute(DataManager dm);
    }

    public class LinearRegressionCost : Cost
    {
        public override static void Compute(DataManager dm)
        {
            double m = dm.Y.Count; // number of training examples
            Vector<double> sigmoidValue = Sigmoid.Compute((dm.X).Multiply(dm.Theta));
            int r = 1;
            dm.J = (1 / m) * (-dm.Y.PointwiseMultiply(sigmoidValue.PointwiseLog()) - (r.PointwiseSubtraction(dm.Y).PointwiseMultiply((r.PointwiseSubtraction(sigmoidValue)).PointwiseLog()))).Sum();
        }
    }

    public class LogisticRegressionCost : Cost
    {
        public override static void Compute(DataManager dm)
        {
            int r = 1;
            double m = dm.Y.Count; // number of training examples
            Vector<double> sigmoidValue = Sigmoid.Compute((dm.X).Multiply(dm.Theta));
            dm.J = (1 / m) * (-dm.Y * (MoreMath.Log(sigmoidValue)) - ((new DenseVector(dm.Y.Count, 1) - dm.Y) * (MoreMath.Log(r.PointwiseSubtraction(sigmoidValue)))));
        }
    }
}
